package com.hospital.hospitalserver.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 收费付款订单编码生成工具类
 * 规则：PAY + 日期时间(12位) + 序列号(8位)
 * 示例：PAY20251107100300000001
 */

public class generatePaymentNo {
    // 付款订单前缀
    private static final String PAYMENT_PREFIX = "PAY";

    // 日期时间格式
    private static final DateTimeFormatter DATE_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyyMMddHHmm");

    // 序列号格式化（8位数字）
    private static final String SEQUENCE_FORMAT = "%08d";

    // 序列号（使用AtomicInteger保证线程安全）
    private static final AtomicInteger SEQUENCE = new AtomicInteger(0);

    // 随机数生成器
    private static final Random RANDOM = new Random();

    // 最大序列号
    private static final int MAX_SEQUENCE = 99999999;

    // 上次生成日期（用于判断是否需要重置序列号）
    private static String lastGenerateDate = "";

    /**
     * 生成付款订单编号
     * @return 付款订单编号，格式：PAY + 日期时间(12位) + 序列号(8位)
     */
    public static synchronized String generatePaymentOrderNo() {
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        String currentDate = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 如果日期变化，重置序列号
        if (!currentDate.equals(lastGenerateDate)) {
            SEQUENCE.set(0);
            lastGenerateDate = currentDate;
        }

        // 生成序列号（如果达到最大值，从随机数重新开始）
        int sequenceNum;
        if (SEQUENCE.get() >= MAX_SEQUENCE) {
            sequenceNum = RANDOM.nextInt(10000000); // 0-9999999
        } else {
            sequenceNum = SEQUENCE.incrementAndGet();
        }

        // 格式化序列号
        String sequenceStr = String.format(SEQUENCE_FORMAT, sequenceNum);

        // 组合付款订单编号
        return PAYMENT_PREFIX + now.format(DATE_TIME_FORMATTER) + sequenceStr;
    }

    /**
     * 生成付款订单编号（带支付渠道）
     * @param paymentChannel 支付渠道
     * @return 付款订单编号，格式：PAY + 支付渠道 + 日期时间(12位) + 序列号(8位)
     */
    public static String generatePaymentOrderNo(String paymentChannel) {
        String baseOrderNo = generatePaymentOrderNo();
        return baseOrderNo.substring(0, 3) + paymentChannel + baseOrderNo.substring(3);
    }

    /**
     * 生成付款订单编号（带业务类型和支付渠道）
     * @param businessType 业务类型
     * @param paymentChannel 支付渠道
     * @return 付款订单编号
     */
    public static String generatePaymentOrderNo(String businessType, String paymentChannel) {
        String baseOrderNo = generatePaymentOrderNo();
        return PAYMENT_PREFIX + businessType + paymentChannel +
                baseOrderNo.substring(3, 15) + baseOrderNo.substring(15);
    }

    /**
     * 验证付款订单编号格式是否正确
     * @param paymentOrderNo 付款订单编号
     * @return 是否有效
     */
    public static boolean isValidPaymentOrderNo(String paymentOrderNo) {
        if (paymentOrderNo == null || paymentOrderNo.length() < 23) {
            return false;
        }

        // 检查前缀
        if (!paymentOrderNo.startsWith(PAYMENT_PREFIX)) {
            return false;
        }

        // 基础格式验证（PAY + 12位日期时间 + 8位序列号）
        if (paymentOrderNo.length() == 23) {
            String dateTimePart = paymentOrderNo.substring(3, 15);
            String sequencePart = paymentOrderNo.substring(15);

            return dateTimePart.matches("\\d{12}") && sequencePart.matches("\\d{8}");
        }

        return true;
    }

    /**
     * 从付款订单编号中提取生成时间
     * @param paymentOrderNo 付款订单编号
     * @return 生成时间，格式：yyyy-MM-dd HH:mm
     */
    public static String getPaymentGenerateTime(String paymentOrderNo) {
        if (!isValidPaymentOrderNo(paymentOrderNo)) {
            throw new IllegalArgumentException("无效的付款订单编号格式");
        }

        // 提取日期时间部分（基础格式：从第3位开始12位数字）
        String dateTimeStr = paymentOrderNo.substring(3, 15);
        try {
            LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr,
                    DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
            return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        } catch (Exception e) {
            throw new IllegalArgumentException("无法从订单编号中解析时间信息");
        }
    }

    /**
     * 从付款订单编号中提取序列号
     * @param paymentOrderNo 付款订单编号
     * @return 序列号
     */
    public static String getSequenceNumber(String paymentOrderNo) {
        if (!isValidPaymentOrderNo(paymentOrderNo)) {
            throw new IllegalArgumentException("无效的付款订单编号格式");
        }

        // 基础格式：最后8位是序列号
        return paymentOrderNo.substring(paymentOrderNo.length() - 8);
    }

    /**
     * 批量生成付款订单编号
     * @param count 生成数量
     * @return 付款订单编号数组
     */
    public static String[] generateBatchPaymentOrderNos(int count) {
        if (count <= 0 || count > 1000) {
            throw new IllegalArgumentException("生成数量必须在1-1000之间");
        }

        String[] orderNos = new String[count];
        for (int i = 0; i < count; i++) {
            orderNos[i] = generatePaymentOrderNo();
            // 添加微小延迟避免重复
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        return orderNos;
    }

    /**
     * 生成退款订单编号
     * @return 退款订单编号，格式：REF + 日期时间(12位) + 序列号(8位)
     */
    public static String generateRefundOrderNo() {
        String paymentOrderNo = generatePaymentOrderNo();
        return "REF" + paymentOrderNo.substring(3);
    }

    /**
     * 生成不同支付渠道的订单编号
     */
    public static class PaymentChannels {
        public static final String WECHAT = "WX";
        public static final String ALIPAY = "AL";
        public static final String UNIONPAY = "UP";
        public static final String BANK = "BK";
        public static final String CASH = "CS";
    }

    /**
     * 生成不同业务类型的订单编号
     */
    public static class BusinessTypes {
        public static final String RECHARGE = "RC"; // 充值
        public static final String CONSUME = "CO";  // 消费
        public static final String FINE = "FI";     // 罚款
        public static final String FEE = "FE";      // 费用
        public static final String SALARY = "SA";   // 工资
    }
}
